<PUBLIC:PROPERTY NAME="AUTOHILITE" INTERNALNAME="m_bAutoHilite" HELPSTRING="Allows the author to restrict the behavior to processing the element to which it is attached; otherwise the entire document is processed." />
<PUBLIC:PROPERTY NAME="TOPICNAME" INTERNALNAME="m_sTopicName" HELPSTRING="Sets or retrieves the name of the topic if the topic documents a reference page" />
<PUBLIC:PROPERTY NAME="PERSISTENTNAME" INTERNALNAME="m_sPN" HELPSTRING="Sets or retrieves the persistent name of the topic if the topic documents a reference page" />
<PUBLIC:PROPERTY NAME="COMMENTMARKERCOLOR" INTERNALNAME="m_sMarkerColor" HELPSTRING="Sets or retrieves the comment marker color" />
<PUBLIC:PROPERTY NAME="COMMENTTEXTCOLOR" INTERNALNAME="m_sTextColor" HELPSTRING="Sets or retrieves the comment text color" />
<SCRIPT>
/*
The behavior's job is to decorate a syntax block.
The behavior works in two modes: decorate the current element, or decorate all PREs marked with the AUTOHILITE expando.
The advantage to the latter mode is that only a single instance of the behavior need be attached to process the entire document.
This works well when the document uses consistent markup for sample code. Attaching one behavior per element wastes resources unnecessarily.
The behavior exposes TOPICNAME and PERSISTENTNAME properties so that the author doesn't have to specify these in the HILITE expando of every
element to be decorated. It's up to the user to set these expandos prior to attaching the behavior.
Future enhancements:
1) In batch mode, rather than processing PREs only, expose a property ELEMENTSTODECORATE that specifies a
semi-colon delimited list of tags that should be inspected for the AUTOHILITE attribute
2) Expose distinct properties for the different marker/text colors
*/
var m_sTopicName = null; // runtime name of the topic
var m_sPN = null; // persistent name of the topic
var m_oRng = null; // TextRange representing the current element
var m_sBM = null; // TextRange bookmark
var m_bAutoHilite = false; // indicates that we should decorate the current element only
var m_sMarkerColor = "blue"; // color for comment delimeters
var m_sTextColor = "green"; // color for text within comments
var m_bScriptPage = false;//Indicates if the page is a script page
function handle_docready()
{
m_oRng = window.document.body.createTextRange();
if (!m_oRng)
{
return;
}
var colMeta=window.document.all.tags("META");
if (colMeta)
{
for (var iMETAs=0; iMETAs<colMeta.length; iMETAs++)
{
if (colMeta[iMETAs].getAttribute("content")=="'scr'" && colMeta[iMETAs].getAttribute("name")=="devlang")
{
m_bScriptPage=true;
}
}
}
if (m_bAutoHilite) // we're attached directly to the element we've been asked to hilite
{
DecorateElement(element);
}
else
{
// walk the entire topic, and decorate special block elements
var oPREs = window.document.all.tags("PRE");
var iPREs = oPREs.length;
if (iPREs == 0)
{
return;
}
for (var iPRE = 0; iPRE < iPREs; iPRE++)
{
var oPRE = oPREs[iPRE];
// only auto-hilite the contents if the feature has been enabled for this PRE
if (oPRE.getAttribute("AUTOHILITE"))
{
DecorateElement(oPRE);
}
}
}
}
function DecorateElement(oElem)
{
m_oRng.moveToElementText(oElem);
m_sBM = m_oRng.getBookmark(); // save our place in case we have to move the range
HiliteComments(m_oRng);
HiliteTokens(oElem, m_oRng);
if (oElem.previousSibling && oElem.previousSibling.ShowHideType )
{
toggle(oElem.previousSibling);
}
}
// restore our place
function RestoreRange()
{
m_oRng.moveToBookmark(m_sBM);
}
// Dispatch calls to the various routines that hilite different code comment types
function HiliteComments(oRng)
{
HiliteCStyleComments(oRng);
HiliteSingleLineComment(oRng, "//");
if (m_bScriptPage)
{
HiliteHTMLComments(oRng);
}
// HiliteSingleLineComment(oRng, "'");
}
// Hilites comments of the following form
// // C++ or JScript comment
// ' VB(S) comment
// # Perl(Script) comment
function HiliteSingleLineComment(oRng, sToken)
{
if (typeof(sToken) != "string")
{
return;
}
var oRngStart = oRng.duplicate();
var oRngEnd;
while (oRngStart.findText(sToken, 1000000) && oRng.inRange(oRngStart))
{
// handle exceptions
if (sToken == "//")
{
var sBM = oRngStart.getBookmark();
oRngStart.move("character", -1);
oRngStart.moveEnd("character", 1);
var sPrecedingChar = oRngStart.text;
oRngStart.moveToBookmark(sBM);
if (sPrecedingChar == ":") // the token is likely part of an http (or some other protocol) link
{
oRngStart.collapse(false);
continue;
}
else if (sPrecedingChar == "-") // part of a DOCTYPE decl?
{
oRngStart.move("character", -2);
oRngStart.moveEnd("character", 1);
var sQuote = oRngStart.text;
if (/(["'])/.test(sQuote))
{
oRngStart.collapse(false);
if (oRngStart.findText(RegExp.$1)) // look for matching quote at the end of the DOCTYPE
{
oRngStart.collapse(false);
continue;
}
else
{
// bad news
return;
}
}
else
{
oRngStart.moveToBookmark(sBM); // reset and proceed